/*
@author: xyl
@file: sanle_shopping.go
@time: 2022/11/20 15:20
*/
package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strconv"
	"strings"
)

// panic: assignment to entry in nil map
// 直接申明map类型, 没有赋值 指向都是nil
// var user2 map[string]string
// make方法分配确定的内存地址
var user = make(map[string]map[string]interface{})

// 存放用户信息  {"sc":{"passwd":"123456", "money":"300"}}
// var user map[string]map[string]interface{}
// 存放商品信息
// {"F001": {"name":"apple", "price":"9"},
//
//	"F002": {"name":"banana", "price":"3"}}
var products = map[string]map[string]interface{}{
	"F001": {"name": "apple", "price": 9},
	"F002": {"name": "banana", "price": 3},
	"F003": {"name": "orange", "price": 4},
}

var user_file string = "user.txt"
var car = make(map[string][][]string)

func main() {
	//执行用户信息初始化函数
	init_user()

	fmt.Println("*********欢迎进入购物系统*****")
	fmt.Println("1、登录")
	fmt.Println("2、注册")
	flag := 0
	for {
		if flag == 1 {
			break
		}
		var op string
		var options string
		var product_id string
		var num string
		fmt.Print("请输入你的选择(按q退出)：")
		fmt.Scan(&op)
		switch op {
		case "1":
			var name, passwd string
			fmt.Print("请输入用户名:")
			fmt.Scan(&name)
			fmt.Println("请输入密码:")
			fmt.Scan(&passwd)
			result := login(name, passwd)
			if result {
				fmt.Println("登录成功")
				for true {
					menu()
					fmt.Println("请输入你的选择：")
					fmt.Scanln(&options)
					if options == "1" {
						show_goods()
					} else if options == "2" {
						fmt.Println("请输入要购买商品的编号：")
						fmt.Scanln(&product_id)
						if _, ok := products[product_id]; ok {
							fmt.Println("请输入购买数量：")
							fmt.Scanln(&num)
							add_car(name, product_id, num)
						}
					} else if options == "3" {
						checkout(name)
					} else if options == "4" {
						break
					} else {
						fmt.Println("请输入正确的选择！")
					}
				}
			} else {
				fmt.Println("登录失败")
			}

		case "2":
			var name, passwd string
			fmt.Print("请输入用户名:")
			fmt.Scan(&name)
			fmt.Println("请输入密码:")
			fmt.Scan(&passwd)
			result := register(name, passwd)
			fmt.Println(result)
			if result {
				fmt.Println(user)
			}
		case "q":
			flag = 1
		}
	}
}

// 从文件中读取信息 初始化user
func init_user() {
	content, err := os.ReadFile(user_file) // 只读方式打开文件
	if err != nil {
		fmt.Println("初始化用户信息失败，没有指定文件")
	} else {
		err1 := json.Unmarshal(content, &user)
		if err1 != nil {
			fmt.Println("json格式化失败，初始化用户信息失败！")
		}
	}
}

func login(name string, passwd string) bool {
	file, err := os.OpenFile(user_file, os.O_CREATE|os.O_WRONLY, 666)
	if err != nil {
		fmt.Println("打开文件，读取用户信息失败！")
	} else {
		str_m1, _ := json.Marshal(user)
		file.Write(str_m1)
		fmt.Println("写入用户信息成功！")
	}
	return true
}

func register(name string, passwd string) bool {
	fmt.Println("register  beginning....")
	_, ok := user[name]
	if ok {
		fmt.Println("用户已存在，请重新输入")
		return false
	} else {
		var money int
		fmt.Print("请输入你的充值金额：")
		fmt.Scan(&money)
		var name_map = map[string]interface{}{
			"passwd": passwd,
			"money":  money}
		user[name] = name_map
		fmt.Println("将用户信息写入文件....")
		WriteUserInfo()
		return true
	}
}

// 将用户信息写入文件
func WriteUserInfo() {
	file, err := os.OpenFile(user_file, os.O_CREATE|os.O_WRONLY, 666)
	if err != nil {
		fmt.Println("打开文件，写入用户信息失败！")
	} else {
		str_m1, _ := json.Marshal(user)
		file.Write(str_m1)
		fmt.Println("写入用户信息成功！")
	}
}

func menu() {
	fmt.Println(strings.Repeat("*", 20))
	fmt.Println("1、查看商品列表")
	fmt.Println("2、添加到购物车")
	fmt.Println("3、结算")
	fmt.Println("4、退出")
}

// 展示商品列表
func show_goods() {
	fmt.Println("编号", strings.Repeat(" ", 10), "名称", strings.Repeat(" ", 10), "单价")
	for k, _ := range products {
		fmt.Println(k, strings.Repeat(" ", 9), products[k]["name"], strings.Repeat(" ", 10), products[k]["price"])
	}
}

// 购物车
func add_car(name string, product_id string, num string) {
	value := []string{product_id, num}
	car[name] = append(car[name], value)
	fmt.Println(car)
}

// 结算
func checkout(name string) {
	m1 := int(user[name]["money"].(float64))
	car_list := car[name]
	total := 0
	fmt.Println("编号  ", "名称  ", "单价  ", "数量  ", "总价")
	for _, goods := range car_list {
		goods_name := products[goods[0]]["name"]
		price := products[goods[0]]["price"].(int)
		num, _ := strconv.Atoi(goods[1])
		goods_total := price * num
		total += goods_total
		fmt.Println(goods[0], " ", goods_name, " ", price, " ", goods[1], " ", goods_total)
	}
	fmt.Println("共计：", total)
	if m1 >= total {
		m1 -= total
	} else {
		fmt.Println("余额不足！")
	}
	user[name]["money"] = m1
	WriteUserInfo()
	fmt.Println("账户余额：", user[name]["money"])
}
